package jdbcmapper;

import java.sql.Connection;
import java.util.*;

import com.robaone.dbase.DBManager;
import lotus.domino.*;
/**
 * <p>Title: JDBC Mapper</p>
 *
 * <p>Description: Libraries to copy documents form Lotus Notes to jdbc
 * table</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: The Salvation ARmy</p>
 *
 * @author Ansel Robateau
 * @version 1.1
 */
public class DBMapper {
    private Session m_session;
    private Database m_database;
    private Hashtable<String,Connection> m_dbconnections;
    public static Vector<String> m_log;
    private int m_priority;
    public DBMapper(Session s,Database db) {
        DBMapper.m_log = new Vector<String>();
        this.m_session = s;
        this.m_database = db;
        this.m_dbconnections = new Hashtable<String,Connection>();
        this.m_priority = 0;
    }
    public Session getSession(){
        return this.m_session;
    }
    public Database getDatabase(){
        return this.m_database;
    }
    public void processMapping() throws Exception {
        // Get database connections
        this.getDatabaseConnections();
        // Process database data exports
        this.processDatabases();
        // Close all database connections
        this.closeDatabaseConnections();
    }
    public void processMapping(long duration,long timeout) throws Exception {
    	this.getDatabaseConnections();
    	this.processDatabases(duration, timeout);
    	this.closeDatabaseConnections();
    }
    private void closeDatabaseConnections() {
    	try{
    		Object[] keys = this.m_dbconnections.keySet().toArray();
    		for(int i = 0; i < keys.length;i++){
    			Connection con = (Connection)this.m_dbconnections.get(keys[i]);
    			try{
    				con.close();
    				
    			}catch(Exception e){
    				
    			}finally{
    				this.m_dbconnections.remove(keys[i]);
    			}
    		}
    	}catch(Exception e){
    		
    	}
	}
	public void setPriority(int p){
        this.m_priority = p;
    }
    protected void processDatabases(long duration,long timeout) throws Exception {
    	Mapping map = new Mapping(this,this.getSession(),this.getDatabase());
        map.LoadMapping();
        
        java.util.Date start = new java.util.Date();
        boolean durationreached = false;
        while(durationreached == false){
        	map.ExportDocuments(this.m_priority);
        	this.finalize();
        	Thread.sleep(timeout); 
        	java.util.Date current = new java.util.Date();
        	long milliseconds = current.getTime() - start.getTime();
        	if(milliseconds >= duration){
        		durationreached = true;
        	}
        }
        map.UnloadMapping();
    }
    /**
     * processDatabases
     */
    protected void processDatabases() throws Exception {
        Mapping map = new Mapping(this,this.getSession(),this.getDatabase());
        map.LoadMapping();
        map.ExportDocuments(this.m_priority);
        this.finalize();
        /*
        // Retrieve databases
        DocumentCollection notes_databases = this.getDatabase().search(
                                             "Form = \"Notes Database\"");
        // For each database
        Document notes_database = notes_databases.getFirstDocument();
        while(notes_database != null){
            try{
                NotesDoc db = new NotesDoc(this.getSession(),notes_database);
                // Determine the database name
                String db_name = db.getString("NotesDatabase");
                // Determine the last modification date
                java.util.Date last_modified = db.retrieveDateTime("LastModified");
                // Get field mapping for this database

            }catch(Exception e){
                e.printStackTrace();
            }
            notes_database = notes_databases.getNextDocument();
        }
        */
    }

    public DocumentCollection getFieldMapping(String notesdatabase) throws Exception {
        String str = "Form = \"Field Map\" & "+
                                     "NotesDatabase = "+notesdatabase;
        //System.out.println(str);
        //this.m_log.add(str);
        DocumentCollection mapping = this.getDatabase().search(str);
        //System.out.println("Documents found = " + mapping.getCount());
        //this.m_log.add("Documents found = " + mapping.getCount());
        return mapping;
    }
    public DocumentCollection getSQLTables(DocumentCollection mapping) throws Exception {
        DocumentCollection retval = null;
        String str = "Form = \"SQL Table\"";
        retval = this.getDatabase().search(str);
        return retval;
    }
 	protected void getDatabaseConnections() throws Exception {
        View view = this.getDatabase().getView("SQL Database Connections");
        ViewEntryCollection vc = view.getAllEntries();
        ViewEntry entry = vc.getFirstEntry();
        Document doc;
        while(entry != null){
            doc = entry.getDocument();
            try{
                String driver = doc.getItemValueString("Driver");
                String url = doc.getItemValueString("Url");
                String username = doc.getItemValueString("Username");
                String password = doc.getItemValueString("Password");
                String name = doc.getItemValueString("SQLDatabase");
                Connection con = this.getConnection(driver, url, username,
                        password);
                this.getSQLConnections().put(name, con);
            }catch(Exception e){
                //e.printStackTrace();
            	System.err.println("Error: DBMapper.getDatabaseConnections(): "+e.getMessage());
            	//DBMapper.m_log.add("Error: DBMapper.getDatabaseConnections(): "+e.getMessage());
            }
            entry = vc.getNextEntry();
        }
    }
	public Hashtable<String, Connection> getSQLConnections(){
        return this.m_dbconnections;
    }
    public Connection getConnection(String name) throws Exception{
        return (Connection)this.m_dbconnections.get(name);
    }
    public Connection getConnection(String driver,String url,String user,String password) throws Exception {
        Connection con = DBManager.getConnection(driver,url,user,password);
        return con;
    }

	public Vector<String> getM_log() {
        return m_log;
    }
    protected void finalize(){
    	try{
    		String data = "<?xml version\"1.0\"?>\n";
    		data += "<logentries>\n";
    		for(int i = 0; i < this.getM_log().size();i++){
    			String event = (String)this.getM_log().get(i);
    			data += "<event>" + event +"</event>\n";
    		}
    		data += "</logentries>";
    		Connection con = this.getConnection("log");
    		//AgentRunnerBase.LogEvent("DBMapper", this.getDatabase().getTitle(), this.getDatabase().getServer(), "Logs", data, con, "agentlog");
    		DBMapper.m_log = new Vector<String>();
    	}catch(Exception e){
    		
    	}
    }
}
